之前在傳統函式有介紹到,參數的傳入有一個 arguments 參數會來承接所有船入的參數,並且使用**類陣列(Array-liked)**的方式記錄起來。
const nums = function () {
console.log(arguments);
}
nums(1,2,3,4,6,7,8,500,10);
但箭頭函式則沒有這個參數,那麼當如果我們需要記錄傳進來的參數的時候,該怎麼辦呢?
const nums = () => {
console.log(arguments);
}
nums(1,2,3,4,6,7,8,500,10);
這個時候就可以使用其餘參數運算子來解決這個問題,利用三個點+自定義變數名稱,就可以將參數的內容以陣列的方式記錄在變數上嚕!
const nums = (...arg) => {
console.log(arg);
}
nums(1,2,3,4,6,7,8,500,10);
箭頭函式沒有自己的 This,怎麼說呢?
我們先來看看範例~
var myName = '全域';
var person = {
myName: '小明',
callName: function () {
console.log('1', this.myName);
setTimeout(function () {
console.log('2', this.myName);
console.log('3', this);
}, 10);
}
}
person.callName();
看完這樣的程式碼,我們可以知道 callName 這個函式中,this的指向會是 person 這個物件。
另外,setTimeout 因為傳入的是 callback function ,所以這裡面的作用域的 this 指向是全域的物件 window。
結果很明顯會是:
那麼我們稍微改動一下程式碼,把 callback function 改成箭頭函式的寫法,看看 this 會怎麼指向~
var myName = '全域';
var person = {
myName: '小明',
callName: function () {
console.log('1', this.myName);
setTimeout(() => {
console.log('2', this.myName);
console.log('3', this);
}, 10);
}
}
person.callName();
可以看到,this 的指向變成了外層作用域的 person。
那麼這個時候,再把 callName 的傳統函式也改成箭頭函式的寫法的話呢?
var myName = '全域';
var person = {
myName: '小明',
callName: () => {
console.log('1', this.myName);
setTimeout(() => {
console.log('2', this.myName);
console.log('3', this);
}, 10);
}
}
person.callName();
很明顯,改成箭頭函式以後,this的指向就跑到全域的物件 window 身上。
而且不管埋幾層都一樣~
var odin = '1';
var obj = {
odin: '2',
arrfn: () => {
console.log('2',this, this.odin)
setTimeout(() => {
console.log('2-setTimeout',this, this.odin)
}, 10);
},
obj: {
odin: '3',
arrfn: () => console.log('3',this, this.odin),
obj: {
odin: '4',
arrfn: function () { console.log('4',this, this.odin)},
obj: {
odin: '5',
arrfn: function () {
console.log('5',this, this.odin)
setTimeout(() => {
console.log('5-setTimeout',this, this.odin)
}, 10);
},
}
}
}
};
obj.arrfn();
obj.obj.arrfn();
obj.obj.obj.arrfn();
obj.obj.obj.obj.arrfn();
只是如果改成傳統函式的話,規則又會跟之前的一樣,在被呼叫的時候,前一個的物件為 this 的指向。
const ele = document.querySelector('p');
ele.addEventListener('click', function () {
console.log(this);
});
一般來說,這樣撰寫以後,點擊畫面上的 p 元素,this 會指向該 p 元素的 DOM。
但如果用箭頭函式撰寫的話~
const ele = document.querySelector('p');
ele.addEventListener('click', () => {
console.log(this);
});
就會指向全域的物件 window 身上。
因為箭頭函式沒有自己的 this,所以就算使用 call, apply, bind 重新給予 this 的指向,也無法改變。
const family = {
myName: '小明家'
};
const fn = (para1, para2) => {
console.log(this, para1, para2);
};
fn.call(family, '小明', '杰倫');
const Fn = function (a) {
this.a = a;
}
const ArrowFn = (a) => {
this.a = a;
}
console.log('Fn', Fn.prototype);
console.log('ArrowFn', ArrowFn.prototype);
const instanceFn = new Fn('a');
const instanceArrowFn = new ArrowFn('a');
以上就是五個傳統函式與箭頭函式不同的地方,其中第二點最容易搞混,要搞清楚再往下走會比較好喔!
沒問題的話就繼續吧!汪汪~